#include "programset.h"
#include "programengine.h"
#include "regdata.h"
#include "modbuswriteinstruction.h"
#include "modbuswriteinstructionlogic.h"
#include "modbusmanager.h"
#include "GeneralDefine.h"
#include "messagelog.h"

extern ModbusManager *modbusManager;

ModbusWriteInstructionLogic::ModbusWriteInstructionLogic(int robotIdIn, ProgramSet *programSetIn, ProgramEngine *programEngineIn, RegData *regDataIn)
{
    robotId = robotIdIn;
    programSet = programSet;
    programEngine = programEngineIn;
    regData = regDataIn;
}

E_PROGRAM_LOOP_RESULT ModbusWriteInstructionLogic::startModbusWrite(int programNumIn, const ModbusWrite &instructionIn, int lineIndex)
{
    Q_UNUSED(lineIndex);
    if(instructionIn.instructionType != MODBUS_WRITE)
    {
        addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  12081, robotId, programEngine->getRunningLineFloat());
        return E_PROGRAM_LOOP_RESULT_ERROR;
    }

    int tmpValue;
    if(CONST_DATA==instructionIn.writeSourceType)
    {
        tmpValue=instructionIn.constWriteData;
    }
    else if(REG_CONST==instructionIn.writeSourceType)
    {
        double regValue;
        regData->getRRegValue(instructionIn.robotRegisterIndex-1,regValue);
        tmpValue=regValue;
    }

    // Modbus-Rs485主机模式
    if(instructionIn.modbusType == E_MODBUS_SPEC_TYPE_RS485_MASTER)
    {
        if(1!=writeModbusRtuClient(instructionIn.busId.toInt(),tmpValue,
                                  instructionIn.modbuWriteRegAddress))
        {
            addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  120103, robotId, programEngine->getRunningLineFloat());
            return E_PROGRAM_LOOP_RESULT_ERROR;
        }

    }
    // Modbus-Rs485从机模式
    else if(instructionIn.modbusType == E_MODBUS_SPEC_TYPE_RS485_SLAVE)
    {
        addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  120101, robotId, programEngine->getRunningLineFloat());
        return E_PROGRAM_LOOP_RESULT_ERROR;
    }
    // Modbus-TCP主机模式
    else if(instructionIn.modbusType == E_MODBUS_SPEC_TYPE_INTERNET_MASTER)
    {

        if(1!=writeModbusTcpClient(instructionIn.busId,tmpValue,
                                  instructionIn.modbuWriteRegAddress))
        {
            addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  120102, robotId, programEngine->getRunningLineFloat());
            return E_PROGRAM_LOOP_RESULT_ERROR;
        }

    }
    // Modbus-TCP从机模式
    else if(instructionIn.modbusType == E_MODBUS_SPEC_TYPE_INTERNET_SLAVE)
    {

        if(1!=writeModbusTcpServer(instructionIn.busId.toInt(),tmpValue,
                                  instructionIn.modbuWriteRegAddress))
        {
            addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  120102, robotId, programEngine->getRunningLineFloat());
            return E_PROGRAM_LOOP_RESULT_ERROR;
        }
    }
    // ERROR
    else if(instructionIn.modbusType == E_MODBUS_SPEC_TYPE_ERROR)
    {

        addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  12082, robotId, programEngine->getRunningLineFloat());
        return E_PROGRAM_LOOP_RESULT_ERROR;
    }


    programEngine->calculateNextLineToRun(programNumIn);
    return E_PROGRAM_LOOP_RESULT_NORMAL;
}

int ModbusWriteInstructionLogic::writeModbusTcpServer(int portIn, int writeValue, int modbusRegisterAddress)
{
    if(1==modbusManager->writeModbusRegister_Server(1,portIn,modbusRegisterAddress,writeValue))
    {
        return 1;
    }
    return -1;

}

int ModbusWriteInstructionLogic::writeModbusTcpClient(QString ipAndPort, int writeValue, int modbusRegisterAddress)
{
    if(1==modbusManager->writeModbusRegister_TcpClient(ipAndPort,modbusRegisterAddress,writeValue))
    {
        return 1;
    }
    return -1;
}

int ModbusWriteInstructionLogic::writeModbusRtuClient(int slaveIdIn, int writeValue, int modbusRegisterAddress)
{
    if(1==modbusManager->writeModbusRegister_rtuClient(slaveIdIn,modbusRegisterAddress,writeValue))
    {
        return 1;
    }
    return -1;
}

void ModbusWriteInstructionLogic::addMsg(int messageLevel, string componentName, string messageType, int messageCode, int robotId, int parameter1, int parameter2, int parameter3, int parameter4, QString message)
{
    Q_UNUSED(parameter2);
    Q_UNUSED(parameter3);
    Q_UNUSED(parameter4);

    Message tmpMsg;
    tmpMsg.MessageLevel = messageLevel;
    tmpMsg.componentClassName = componentName;
    tmpMsg.messageType = messageType;
    tmpMsg.robotId = robotId;
    tmpMsg.messageCode = messageCode;

    QString infomationStr;

    switch(messageCode)
    {
    case 120103:
    {
         infomationStr = QObject::tr("机器人:") +
             QString::number(robotId) +
             QObject::tr("第") +
             QString::number(parameter1+1) +
             QObject::tr("行运行出现异常:写ModbusRtu失败!")+message;
         break;
    }
    case 120102:
    {
         infomationStr = QObject::tr("机器人:") +
             QString::number(robotId) +
             QObject::tr("第") +
             QString::number(parameter1+1) +
             QObject::tr("行运行出现异常:写ModbusTcp失败!")+message;
         break;
    }
    case 120101:
    {
         infomationStr = QObject::tr("机器人:") +
             QString::number(robotId) +
             QObject::tr("第") +
             QString::number(parameter1+1) +
             QObject::tr("行运行出现异常:ModbusWrite暂时不支持的参数模式!")+message;
         break;
    }
       case 120100:
       {
            infomationStr = QObject::tr("机器人:") +
                QString::number(robotId) +
                QObject::tr("第") +
                QString::number(parameter1+1) +
                QObject::tr("行运行出现异常:ModbusWrite数据发送失败!")+message;
            break;
       }
        default:
       {
            break;
       }
    }
    tmpMsg.MessageInformation = infomationStr.toStdString();
    MessageLog::getInstance()->addMessage(tmpMsg);
}
